Skip to content

test: make assert_linequal ignore dimension order#801

Merged
FabianHofmann merged 2 commits into
PyPSA:masterfrom
fluxopt:fix/assert-linequal-dim-order
Jul 14, 2026
Merged

test: make assert_linequal ignore dimension order#801
FabianHofmann merged 2 commits into
PyPSA:masterfrom
fluxopt:fix/assert-linequal-dim-order

Conversation

@FBumann

@FBumann FBumann commented Jun 30, 2026

Copy link
Copy Markdown
Collaborator

I hit some false positives while working on sth else. This fixes them. Making the testing more robust.

Note

The following content was generated by AI.

What this does

linopy expressions are dimension-labelled xarray structures, so they inherit
xarray's broadcast order-sensitivity: x + y produces dims (x_dim, y_dim)
while y + x produces (y_dim, x_dim). That difference is not mathematically
meaningful, but xarray's assert_equal is order-sensitive, so
assert_linequal(x + y, y + x) failed.

assert_linequal already normalizes term order before comparing (its
docstring promises "semantically equal"). This aligns dimension order the
same way: a new _align_dim_order helper transposes the second operand to the
first's dimension order when they share a dimension set. If the dimension sets
differ, the expressions are genuinely unequal and the comparison is left
untouched so assert_equal reports the real difference.

Notes

  • Touches only linopy/testing.py; adds test/test_testing.py (dim-order
    insensitivity, plus genuinely-different expressions still fail).
  • Full test_linear_expression.py + test_quadratic_expression.py pass
    unchanged (333), i.e. nothing was relying on the order-sensitive behavior.
Reproducer
import pandas as pd
from linopy import Model
from linopy.testing import assert_linequal

m = Model()
a = m.add_variables(coords=[pd.Index([0, 1], name="i")], name="a")
b = m.add_variables(coords=[pd.Index([0, 1, 2], name="j")], name="b")

(a + b).data.coeffs.dims   # ('i', 'j', '_term')
(b + a).data.coeffs.dims   # ('j', 'i', '_term')
assert_linequal(a + b, b + a)   # before: AssertionError; after: passes

linopy expressions inherit xarray's broadcasting, whose dimension order
follows operand order: ``x + y`` yields ``(x_dim, y_dim)`` while ``y + x``
yields ``(y_dim, x_dim)``. That difference carries no mathematical meaning,
yet xarray's order-sensitive ``assert_equal`` made the two compare unequal.

``assert_linequal`` already normalizes term order; align dimension order the
same way before comparing, matching its "semantically equal" contract.
Expressions with genuinely different dimension sets or values still fail.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@codspeed-hq

codspeed-hq Bot commented Jun 30, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 173 untouched benchmarks
⏩ 173 skipped benchmarks1


Comparing fluxopt:fix/assert-linequal-dim-order (0843da9) with master (0420563)

Open in CodSpeed

Footnotes

  1. 173 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

@FBumann FBumann requested a review from FabianHofmann June 30, 2026 20:42
@FBumann

FBumann commented Jun 30, 2026

Copy link
Copy Markdown
Collaborator Author

canceled pypsa-tests

@FabianHofmann FabianHofmann merged commit a6ca0be into PyPSA:master Jul 14, 2026
23 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants